/*
 * 
 * SFL java Trading System Enviroment
 * Copyright (C) 2005 Alberto Sfolcini <a.sfolcini@gmail.com>
 * 
 * This file is a part of sfljtse.
 * 
 * sfljtse is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * sfljtse is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 *
 */
package averages;

import averages.model.AbstractMA;
import averages.model.IMA;

/**
 * @title		: T3       
 * @description	: T3 is a six-pole non-linear Kalman filter. 
 *                Kalman filters are ones which use the error 
 *                (in this case (time series - EMA(n)) to correct themselves. 
 *                In Technical Analysis, these are called Adaptive Moving Averages; 
 *                they track the time series more aggressively when it is making large moves.
 * @date		: 15-set-2005   
 * @author		: Alberto Sfolcini  <a.sfolcini@gmail.com>
 */
public class T3 extends AbstractMA implements IMA{

    public static final int EMA = 0;
    public static final int AMA = 1;

    private int type = EMA;
    
    /**
     * Constructor
     */
    public T3(double[] value, int periods) {
        super(value, periods);
        this.type = EMA;
        calc();
    }

    /**
     * Constructor
     */
    public T3(double[] value, int periods,int type) {
        super(value, periods);
        this.type = type;
        calc();
    }

    //public void calc() {
        
      
      //  }
        
  //  }

    private double[] t3(double _s,double e1[],double e2[],double e3[],double e4[],double e5[],double e6[]){
        int size = value.length;
        double s = _s;
        double c1[] = new double[size];
        double c2[] = new double[size];
        double c3[] = new double[size];
        double c4[] = new double[size];
        double t3[] = new double[size];
        
        for (int i=periods;i<size;i++){
            c1[i] = -s*s*s;
            c2[i] = 3*s*s+3*s*s*s;
            c3[i] = -6*s*s-3*s-3*s*s*s;
            c4[i] = 1+3*s+s*s*s+3*s*s;
            t3[i] = c1[i]*e6[i]+c2[i]*e5[i]+c3[i]*e4[i]+c4[i]*e3[i];
        }
        return t3;
    }

    public double[] calc() {
          int size = value.length;
        
        switch (type){
            case AMA:{
                // AMA based
                if (periods>size){
                    for (int i=0;i<size;i++)
                        ma[i] = 0.0;
                } else {
                    // AMA based
                    double s = 0.84;
                    AMA e1 = new AMA(value,periods);
                    AMA e2 = new AMA(e1.ma,periods);
                    AMA e3 = new AMA(e2.ma,periods);
                    AMA e4 = new AMA(e3.ma,periods);
                    AMA e5 = new AMA(e4.ma,periods);
                    AMA e6 = new AMA(e5.ma,periods);
                
                    this.ma = t3(s,e1.ma,e2.ma,e3.ma,e4.ma,e5.ma,e6.ma);
                }
                break;
            }
            case EMA:{
                // EMA based, default T3 calculation
                if (periods>size){
                    for (int i=0;i<size;i++)
                        ma[i] = 0.0;
                } else {
                    double s = 0.84;
                    EMA e1 = new EMA(value,periods);
                    EMA e2 = new EMA(e1.ma,periods);
                    EMA e3 = new EMA(e2.ma,periods);
                    EMA e4 = new EMA(e3.ma,periods);
                    EMA e5 = new EMA(e4.ma,periods);
                    EMA e6 = new EMA(e5.ma,periods);
                
                    this.ma = t3(s,e1.ma,e2.ma,e3.ma,e4.ma,e5.ma,e6.ma);
                    
                } // end else
            }
                
    }
        return ma;
    }
}
